package org.fungene.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import org.fungene.services.db.AccessBioDBClient;
import org.fungene.services.db.AccessBioDBPortType;
import org.fungene.util.chart.ChartConstant;
import org.fungene.util.chart.ChartUtil;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.servlet.ServletUtilities;
import org.jfree.data.category.DefaultCategoryDataset;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

public class QueryController extends AbstractController {

	@Override
	protected ModelAndView handleRequestInternal(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		// DB Service stub
		AccessBioDBClient client = new AccessBioDBClient();
		AccessBioDBPortType service = client.getAccessBioDBHttpPort();
		

		// Request Parameters
		String[] reqPlatforms = request.getParameter("platformList").trim()
				.split("[,\\s]+");
		String[] keywords = request.getParameter("keyword").trim().split(
				"[,\\s]+");

		List<String> platforms = service.getPlatforms().getString();

		List<String> result = new ArrayList<String>();

		for (String platform : platforms) {
			for (String reqPlatform : reqPlatforms) {
				/*
				 * 判断关键词和系统内Platform(现在使用TableName)的对应关系 现在的写法很弱智
				 * 最好在数据库中添加Platform列
				 */
				if (platform.contains(reqPlatform)) {
					for (String keyword : keywords) {
						System.out.println("Search " + keyword + " in "
								+ platform);

						result
								.addAll(service.runQuery(platform,
								/* 这个地方的参数写的也非常之烂 */"genename=" + keyword)
										.getString());
					}
				}
			}
		}

		response.getWriter().write(genReturn(result));
		return null;
	}

	private String genReturn(List<String> resultList) {
		System.out.println(resultList.size() + " results are listed.");
		JSONObject resultJSON = new JSONObject();
		JSONObject singleJSON = new JSONObject();
		String[] beanParts = new String[5];
		HashMap<String, Integer> counterMap = new HashMap<String, Integer>();

		DefaultCategoryDataset dataset = new DefaultCategoryDataset();
		/*
		 * resultList order: "probe_id value cellLine geneName tissue";
		 * 
		 * Generate JSON Object for counter: "preRun":[ {"geneName": name,
		 * "value": 0.0, "probeId": 0, "cellLine": name, "tissue": name}]
		 */
		for (String singleResult : resultList) {
			singleJSON.clear();
			beanParts = singleResult.split("[\\s]+");
			String key = beanParts[3];
			singleJSON.put("geneName", key);
			singleJSON.put("value", beanParts[1]);
			singleJSON.put("probeId", beanParts[0]);
			singleJSON.put("cellLine", beanParts[2]);
			singleJSON.put("tissue", beanParts[4]);
			dataset.addValue(Double.parseDouble(beanParts[1]), beanParts[0],
					beanParts[2] + ":" + beanParts[4]);

			// Count Match
			if (counterMap.containsKey(key)) {
				counterMap.put(key, counterMap.get(key) + 1);
			} else {
				counterMap.put(key, 1);
			}

			resultJSON.accumulate("preRun", singleJSON);
		}
		/*
		 * Generate JSON Object for counter: "counter":[ {"geneName": name,
		 * "matchCount": 0}]
		 */
		for (String key : counterMap.keySet()) {
			singleJSON.clear();
			singleJSON.put("geneName", key);
			singleJSON.put("matchCount", counterMap.get(key));

			resultJSON.accumulate("counter", singleJSON);
		}

		// jFreeChart to generate picture
		String picURL = "servlet/DisplayChart?filename=";

		ChartUtil chartUtil = new ChartUtil(dataset);
		JFreeChart chart = chartUtil.genByCmd(ChartConstant
				.TypeToCMD(ChartConstant.TYPE_LINE));
		try {
			picURL += ServletUtilities.saveChartAsPNG(chart,
					ChartConstant.PIXEL_X, ChartConstant.PIXEL_Y, null, null);
			System.out.println(picURL);
		} catch (IOException e) {

		}

		singleJSON.clear();
		singleJSON.put("width", ChartConstant.PIXEL_X);
		singleJSON.put("height", ChartConstant.PIXEL_Y);
		singleJSON.put("URL", picURL);

		resultJSON.accumulate("picInfo", singleJSON);

		return resultJSON.toString();
	}
}
